package com.qk.management.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.model.ListObjectsV2Request;
import com.aliyun.oss.model.ListObjectsV2Result;
import com.aliyun.oss.model.OSSObjectSummary;
import com.qk.constant.FileConstant;
import com.qk.management.config.OssPathExtractor;
import com.qk.management.mapper.UserMapper;
import com.qk.management.service.AvatarCleanService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * oss头像清理服务
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AvatarCleanServiceImpl implements AvatarCleanService {

    private  final OSS ossClient;
    private final UserMapper userMapper;
    private final OssPathExtractor ossPathExtractor;
    @Value("${qk.alioss.bucket-name}")
    private String bucketName;
    public void executeAvatarCleanup() {
        log.info("开始执行头像清理任务...");
        try {
            Set<String> ossAvatars = getAllOssAvatars();
            Set<String> dbAvatarPaths = extractValidAvatarOssPaths();
            deleteOrphanedOssFiles(ossAvatars, dbAvatarPaths);
            log.info("头像清理任务执行完成");
        } catch (Exception e) {
            log.error("头像清理任务执行失败", e);
            throw new RuntimeException("头像清理任务执行失败", e);
        }
    }

    private void deleteOrphanedOssFiles(Set<String> ossAvatars, Set<String> dbAvatarPaths) {
        List<String> orphanedFiles = ossAvatars.stream()
                .filter(ossPath -> !dbAvatarPaths.contains(ossPath))
                .toList();
        if (!orphanedFiles.isEmpty()) {
            log.info("发现 {} 个OSS中的垃圾头像文件，开始删除...", orphanedFiles.size());
            for (String filePath : orphanedFiles) {
                try {
                    ossClient.deleteObject(bucketName, filePath);
                    log.debug("已删除OSS垃圾文件: {}", filePath);
                } catch (Exception e) {
                    log.warn("删除OSS文件失败: {}", filePath, e);
                }
            }
        } else {
            log.info("未发现需要删除的OSS垃圾头像文件");
        }
    }

    private Set<String> getAllOssAvatars() {
        Set<String> ossAvatars = new HashSet<>();
        String prefix = FileConstant.AVATAR_UPLOAD_PATH;
        ListObjectsV2Request request = new ListObjectsV2Request(bucketName);
        request.setPrefix(prefix);
        request.setMaxKeys(1000);
        String nextContinuationToken = null;
        ListObjectsV2Result result;
        do {
            if (nextContinuationToken != null) {
                request.setContinuationToken(nextContinuationToken);
            }
            result = ossClient.listObjectsV2(request);
            for (OSSObjectSummary objectSummary : result.getObjectSummaries()) {
                String key = objectSummary.getKey();
                if (isImageFile(key)) {
                    ossAvatars.add(key);
                }
            }
            nextContinuationToken = result.getNextContinuationToken();
            log.debug("已获取 {} 个头像文件，还有更多数据: {}",
                    result.getObjectSummaries().size(), result.isTruncated());
        } while (result.isTruncated());
        log.info("从OSS头像目录获取到 {} 个有效的头像文件", ossAvatars.size());
        return ossAvatars;
    }
    private Set<String> extractValidAvatarOssPaths() {
        List<String> avatarUrls = userMapper.findValidUserAvatarUrls();
        Set<String> ossPaths = new HashSet<>();
        for (String avatarUrl : avatarUrls) {
            String ossPath = ossPathExtractor.extractOssPathFromUrl(avatarUrl);
            if (ossPath != null && !ossPath.trim().isEmpty()) {
                ossPaths.add(ossPath);
            } else {
                log.warn("无法解析头像URL的OSS路径: {}", avatarUrl);
            }
        }
        log.info("从数据库提取到 {} 个有效头像OSS路径", ossPaths.size());
        return ossPaths;
    }

    private boolean isImageFile(String fileName) {
        if (ObjectUtil.isNull(fileName)) {
            return false;
        }
        String lowerCaseName = fileName.toLowerCase();
        return lowerCaseName.endsWith(".jpg") || 
               lowerCaseName.endsWith(".jpeg") ||
               lowerCaseName.endsWith(".png") ||
               lowerCaseName.endsWith(".gif") ||
               lowerCaseName.endsWith(".bmp") ||
               lowerCaseName.endsWith(".webp") ||
               lowerCaseName.endsWith(".svg");
    }
}